home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1996 #15
/
Monster Media Number 15 (Monster Media)(July 1996).ISO
/
bbs_util
/
bsrc_260.zip
/
SRC.ZIP
/
MAILROOT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-03-26
|
21KB
|
883 lines
/*--------------------------------------------------------------------------*/
/* */
/* */
/* ------------ Bit-Bucket Software, Co. */
/* \ 10001101 / Writers and Distributors of */
/* \ 011110 / Freely Available<tm> Software. */
/* \ 1011 / */
/* ------ */
/* */
/* (C) Copyright 1987-96, Bit Bucket Software Co. */
/* */
/* This module was written by Bob Hartman */
/* */
/* BinkleyTerm Mail Control Routines */
/* */
/* */
/* For complete details of the licensing restrictions, please refer */
/* to the License agreement, which is published in its entirety in */
/* the MAKEFILE and BT.C, and also contained in the file LICENSE.260. */
/* */
/* USE OF THIS FILE IS SUBJECT TO THE RESTRICTIONS CONTAINED IN THE */
/* BINKLEYTERM LICENSING AGREEMENT. IF YOU DO NOT FIND THE TEXT OF */
/* THIS AGREEMENT IN ANY OF THE AFOREMENTIONED FILES, OR IF YOU DO */
/* NOT HAVE THESE FILES, YOU SHOULD IMMEDIATELY CONTACT BIT BUCKET */
/* SOFTWARE CO. AT ONE OF THE ADDRESSES LISTED BELOW. IN NO EVENT */
/* SHOULD YOU PROCEED TO USE THIS FILE WITHOUT HAVING ACCEPTED THE */
/* TERMS OF THE BINKLEYTERM LICENSING AGREEMENT, OR SUCH OTHER */
/* AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO. */
/* */
/* */
/* You can contact Bit Bucket Software Co. at any one of the following */
/* addresses: */
/* */
/* Bit Bucket Software Co. FidoNet 1:104/501, 1:343/491 */
/* P.O. Box 460398 AlterNet 7:42/1491 */
/* Aurora, CO 80046 BBS-Net 86:2030/1 */
/* Internet f491.n343.z1.fidonet.org */
/* */
/* Please feel free to contact us at any time to share your comments about */
/* our software and/or licensing policies. */
/* */
/*--------------------------------------------------------------------------*/
/* Include this file before any other includes or defines! */
#include "includes.h"
static char *LOCALFUNC estring (int, int);
static void scan_netmail (char *);
int
do_mail (ADDRP baddr, int type) /* 1 = manual, 0 = normal, -1 = CM */
{
int i;
long callstart = 0, callend;
b_init ();
caller = 1;
got_packet = 0;
got_arcmail = 0;
got_mail = 0;
got_fax = 0;
sent_mail = 0;
no_WaZOO_Session = no_WaZOO;
no_EMSI_Session = no_EMSI;
callstart = 0L;
(void) sprintf (junk, "%s", Full_Addr_Str (baddr));
called_addr = remote_addr = *baddr; /* structure assignment */
if (!net_params)
{
status_line (MSG_TXT (M_INSUFFICIENT_DATA));
set_xy ("");
return (0);
}
if (!nodeproc (junk))
return (0);
if (type > 0)
{
if (flag_file (TEST_AND_SET, &called_addr, 1))
{
if (CARRIER)
mdm_hangup ();
return (0);
}
if (CARRIER || /* called manually maybe? */
(ExtMailMask && (newnodedes.ModemType == (byte)ExtMailMask)))
goto process_the_damned_mail; /* yup, just do some mail */
do_dial_strings ();
try_2_connect ((char *) (newnodedes.PhoneNumber)); /* try to connect */
}
else
{
/* If this is supposed to be only local, then get out if it isn't */
if (type == 0)
{
if (e_ptrs[cur_event].behavior & MAT_LOCAL)
{
if (e_ptrs[cur_event].node_cost < 0)
{
if ((int) newnodedes.RealCost < -e_ptrs[cur_event].node_cost)
{
return (0);
}
}
else
{
if ((int) newnodedes.RealCost > e_ptrs[cur_event].node_cost)
{
return (0);
}
}
}
/* If it is supposed to be 24 hour mail only, get out if it isn't */
if ((newnodelist || version7) &&
(!(e_ptrs[cur_event].behavior & MAT_NOMAIL24)) &&
(!(newnodedes.NodeFlags & B_CM)))
return (0);
/* If we aren't supposed to send to CM's now, get out */
if ((newnodelist || version7) &&
(e_ptrs[cur_event].behavior & MAT_NOCM) &&
(newnodedes.NodeFlags & B_CM))
return (0);
}
/* Try to connect */
if (flag_file (TEST_AND_SET, &called_addr, 1))
{
if (CARRIER)
mdm_hangup ();
return (0);
}
do_dial_strings ();
if (un_attended && fullscreen)
{
sb_move (holdwin, 2, 1);
sb_wa (holdwin, colors.calling, 31);
}
callstart = time (NULL);
if (!blank_on_key)
screen_blank = 0;
if (ExtMailMask && (newnodedes.ModemType == (byte)ExtMailMask))
goto process_the_damned_mail;
if ((i = try_1_connect ((char *) (newnodedes.PhoneNumber))) < 0)
{
if (un_attended && fullscreen)
{
sb_move (holdwin, 2, 1);
sb_wa (holdwin, colors.hold, 31);
}
(void) flag_file (CLEAR_FLAG, &called_addr, 1);
return (i);
}
}
process_the_damned_mail:
if (CARRIER || /* if we did, */
(ExtMailMask && (newnodedes.ModemType == (byte)ExtMailMask)))
{
if (!callstart)
callstart = time (NULL);
b_session (1); /* do a mail session */
if (remote_pickup != -2)
mdm_hangup ();
callend = time (NULL);
hist.last_Elapsed = callend - callstart;
hist.callcost += cost_of_call (1, callstart, callend);
++hist.connects;
if (un_attended && fullscreen)
{
do_today ();
}
write_stats ();
if (un_attended && (got_arcmail || got_packet || got_mail))
{
(void) bad_call (baddr, -1);
receive_exit ();
}
if (un_attended && fullscreen)
{
sb_move (holdwin, 2, 1);
sb_wa (holdwin, colors.hold, 31);
}
return (1);
}
else
{
status_line (MSG_TXT (M_END_OF_ATTEMPT));
(void) flag_file (CLEAR_FLAG, &called_addr, 1);
}
if (un_attended && fullscreen)
{
sb_move (holdwin, 2, 1);
sb_wa (holdwin, colors.hold, 31);
}
write_stats ();
return (2);
}
int
handle_inbound_mail (int answer_now)
{
long t; /* used for timeouts */
long lEndTime; /* master timeout */
int iRingCount = 0; /* for counting 'em */
int mr; /* Modem response */
int iInterval = 6000; /* Default wait = 1min*/
long callstart, callend;
no_WaZOO_Session = no_WaZOO;
no_EMSI_Session = no_EMSI;
caller = 0;
(void) memset ((char *) &remote_addr, 0, sizeof (remote_addr));
remote_addr.Domain = NULL; /* only Microsoft can explain this */
/* Master timeout of 2 minutes */
lEndTime = timerset (12000);
inloop:
/* Do we have carrier, RING, or NO DIAL TONE? */
if (timeup (lEndTime) || ((answer_now <= 0) && !(server_mode && CARRIER) && !CHAR_AVAIL ()))
{
time_release ();
return (0); /* No, nothing to do */
}
mail_only = 1;
if ((cur_event >= 0) && (e_ptrs[cur_event].behavior & MAT_BBS))
mail_only = 0;
if (KEYPRESS ()) /* If aborted by user, */
return (1); /* get out */
if (server_mode && CARRIER)
{
mr = CONNECTED;
goto got_carrier;
}
if (answer_now > 0)
{
mr = RINGING; /* say it rang */
iRingCount = ring_wait; /* we want to answer right now */
answer_now = -1;
}
else
mr = modem_response (500);
if ((mr == RINGING) && (ans_str != NULL)) /* saw RING */
{
iRingCount++;
/* Unblank on the first ring */
if ((answer_now < 0) || (iRingCount == 1))
{
if (!blank_on_key)
screen_blank = 0;
if (un_attended && fullscreen)
sb_show ();
}
/* Answer if we've reached the correct ring number */
if (iRingCount >= ring_wait)
{
/*
* Try to make sure we don't send out the answer string
* while stuff is still coming from the modem. Most modems
* don't like that kind of sequence (including HST's!).
*/
t = timerset (100);
while (CHAR_AVAIL () && (!timeup (t)))
{
t = timerset (100);
(void) MODEM_IN ();
}
CLEAR_INBOUND ();
mdm_cmd_string (ans_str, 0); /* transmit the answer string */
iInterval = 6000;
}
/* Otherwise wait up to 15 seconds for something to happen */
else
iInterval = 1500;
}
else if (mr == FAILURE) /* If we got "No Carrier" */
{
time_release ();
return (0); /* Nothing happened... */
}
else if (mr == CONNECTED || mr >= FAX)
goto got_carrier;
t = timerset (iInterval);/* set the interval timer */
while ((!timeup (t))
&& (!CHAR_AVAIL ())
&& (!KEYPRESS ()))
{
time_release (); /* wait for another result */
}
goto inloop; /* then proceed along */
got_carrier:
if (!blank_on_key)
screen_blank = 0;
if (un_attended && fullscreen)
sb_show ();
callstart = time (NULL);
if (mr >= FAX) /* FAX is > 16 */
{
int gotfax = 1;
int i;
if (!fax_in)
{
/* We have a FAX result code but are not configured to
receive any. See if the user has set up a fax exit
using the external mail strings */
for (i = 0; i < num_ext_mail; i++)
{
if (stricmp (saved_response, ext_mail_string[i]) == 0)
{
last_type (5, &alias[0]);
UUCPexit (lev_ext_mail[i], 0);
}
}
}
else
{
start_hist = hist;
last_type (5, &alias[0]);
gotfax = faxreceive (FAX); /* Try to get a FAX */
}
mdm_hangup (); /* Then hang up */
callend = time (NULL);
hist.last_Elapsed = callend - callstart;
hist.callcost += cost_of_call (0, callstart, callend);
if (gotfax) /* If we got one, */
{
got_fax = 1; /* Say we got mail */
receive_exit (); /* And try to exit */
}
}
else if (CARRIER) /* if we have a carrier, */
{
b_session (0); /* do a mail session */
mdm_hangup (); /* Make sure to hang up */
callend = time (NULL);
hist.last_Elapsed = callend - callstart;
hist.callcost += cost_of_call (0, callstart, callend);
/* We got inbound mail */
if (got_arcmail || got_packet || got_mail)
{
receive_exit ();
}
}
else
{
mdm_hangup (); /* Try to reset modem */
callend = time (NULL);
hist.last_Elapsed = callend - callstart;
hist.callcost += cost_of_call (0, callstart, callend);
}
mailer_banner ();
return (1);
}
void
receive_exit ()
{
char junk1[150];
int i;
BINK_EVENT evt;
if (cur_event >= 0)
evt = e_ptrs[cur_event];
if (cur_event >= 0)
{
int errlvl = 0;
int exitlvl = 0;
if (got_arcmail && (evt.errlevel[2]))
{
exitlvl = evt.errlevel[2];
if (errlvlshell[exitlvl - 1] == NULL)
{
errlvl = exitlvl;
status_line (MSG_TXT (M_EXIT_COMPRESSED), errlvl);
}
else
{
status_line (MSG_TXT (M_SHELL_COMPRESSED), exitlvl);
errl_shell (exitlvl);
got_arcmail = got_mail = got_packet = 0;
}
}
for (i = 0; i < 6; i++)
{
if (user_exits[i])
{
user_exits[i] = 0;
exitlvl = evt.errlevel[i + 3];
if (errlvlshell[exitlvl - 1] == NULL)
{
if (errlvl == 0)
{
errlvl = exitlvl;
status_line (MSG_TXT (M_EXIT_AFTER_EXTENT),
&(evt.err_extent[i][0]), errlvl);
}
}
else
{
status_line (MSG_TXT (M_SHELL_AFTER_EXTENT),
&(evt.err_extent[i][0]), exitlvl);
errl_shell (exitlvl);
}
}
}
#ifdef BINKLEY_SOUNDS
/* If we got an exit level, it's still set even if we shelled.
So use its presence to determine whether to make noise */
if (exitlvl)
Make_Sound (fnFileSound);
#endif
/* See if we still want to exit */
if (errlvl)
errl_exit (errlvl);
}
if (got_fax && cur_event >= 0 && (evt.faxerrlevel))
{
#ifdef BINKLEY_SOUNDS
Make_Sound (fnFAXSound);
#endif
if (errlvlshell[evt.faxerrlevel - 1] != NULL)
{
status_line (MSG_TXT (M_SHELL_FAX), evt.faxerrlevel);
errl_shell (evt.faxerrlevel);
got_fax = 0;
}
else
{
status_line (MSG_TXT (M_EXIT_FAX), evt.faxerrlevel);
errl_exit (evt.faxerrlevel);
}
}
if ((got_fax || got_mail || got_packet) &&
(cur_event >= 0) && (evt.errlevel[1]))
{
#ifdef BINKLEY_SOUNDS
Make_Sound (fnMailSound);
#endif
if (errlvlshell[evt.errlevel[1] - 1] != NULL)
{
status_line (MSG_TXT (M_SHELL_AFTER_MAIL), evt.errlevel[1]);
errl_shell (evt.errlevel[1]);
got_fax = got_mail = got_packet = 0;
}
else
{
status_line (MSG_TXT (M_EXIT_AFTER_MAIL), evt.errlevel[1]);
errl_exit (evt.errlevel[1]);
}
}
if ((aftermail != NULL) && (got_fax || got_mail || got_packet || got_arcmail))
{
status_line (MSG_TXT (M_AFTERMAIL));
#ifdef BINKLEY_SOUNDS
Make_Sound (fnMailSound);
#endif
mdm_init (modem_busy);
exit_DTR ();
screen_clear ();
vfossil_cursor (1);
(void) strcpy (junk1, aftermail);
if (cur_event >= 0)
(void) strcat (junk1, evt.cmd);
close_up ();
b_spawn (junk1);
come_back ();
RAISE_DTR ();
status_line (MSG_TXT (M_OK_AFTERMAIL));
mdm_init (modem_init);
xmit_reset (0);
waitfor_line = timerset ((unsigned int) 6000);
}
got_arcmail = 0;
got_packet = 0;
got_mail = 0;
got_fax = 0;
}
void
errl_exit (int n)
{
write_sched ();
status_line (MSG_TXT (M_BINK_END), ANNOUNCE, COMPILER_NAME);
mdm_init (modem_busy); /* Reinitialize the modem */
exit_DTR ();
if (fullscreen)
gotoxy (0, SB_ROWS);
if (vfossil_installed)
vfossil_close ();
if (!share)
MDM_DISABLE ();
exit (n);
}
void
errl_shell (int n)
{
write_sched ();
if (!strnicmp ("start ", errlvlshell[n - 1], 6))
{
status_line (MSG_TXT (M_START_ERRLVL_SESSION), n);
system (errlvlshell[n - 1]);
}
else
{
mdm_init (modem_busy);
exit_DTR ();
close_up ();
screen_clear ();
vfossil_cursor (1);
b_spawn (errlvlshell[n - 1]);
come_back ();
RAISE_DTR ();
status_line (MSG_TXT (M_RETURN_ERRLVL_SHELL));
mdm_init (modem_init);
xmit_reset (0);
waitfor_line = timerset ((unsigned int) 6000);
}
}
long
random_time (int x)
{
int i;
if (x == 0)
{
return (0L);
}
/* Number of seconds to delay is random based on x +/- 50% */
i = (rand () % (x + 1)) + (x / 2);
return (timerset ((unsigned int) (i * 100)));
}
char *
HoldAreaNameMunge (ADDRP maddr)
{
static char munged[127];
register char *p, *q;
int i;
if ((maddr->Domain != my_addr.Domain) && (maddr->Domain != NULL))
{
*domain_loc = '\0';
(void) strcpy (munged, domain_area);
q = &(munged[strlen (munged)]);
for (i = 0; domain_name[i] != NULL; i++)
{
if (domain_name[i] == maddr->Domain)
{
if (domain_abbrev[i] != NULL)
{
p = domain_abbrev[i];
while (*p)
*q++ = *p++;
if (no_zones)
(void) sprintf (q, "\\");
else
(void) sprintf (q, ".%03x\\", maddr->Zone);
}
break;
}
}
}
else
{
(void) strcpy (munged, hold_area);
q = &(munged[strlen (munged)]);
if (!((maddr->Zone == alias[0].Zone) || (no_zones)))
{
--q;
(void) sprintf (q, ".%03x\\", maddr->Zone);
}
}
return (munged);
}
void
mailer_banner ()
{
if (fullscreen && un_attended)
{
vfossil_cursor (0);
(void) sprintf (junk, "%-2d", cur_event + 1);
sb_move (settingswin, SET_EVNT_ROW, SET_COL);
sb_puts (settingswin, junk);
(void) sprintf (junk, "%-6lu Com%d", cur_baud.rate_value, port_ptr + 1);
sb_move (settingswin, SET_PORT_ROW, SET_COL);
sb_puts (settingswin, junk);
clear_filetransfer ();
if (TaskNumber)
(void) sprintf (junk, "M'Task: %-7s %02x", mtask_name, TaskNumber);
else
(void) sprintf (junk, "M'Task: %s", mtask_name);
sb_move (settingswin, SET_TASK_ROW, 2);
sb_puts (settingswin, " ");
sb_move (settingswin, SET_TASK_ROW, 2);
sb_puts (settingswin, junk);
}
(void) set_baud (max_baud.rate_value, 0);
}
void
clear_filetransfer ()
{
if (fullscreen && un_attended)
sb_fillc (filewin, ' ');
}
static char ebuf[50];
static char *LOCALFUNC
estring (int e, int how_big)
{
char j[30];
char *p, *q;
*(p = &ebuf[0]) = '\0';
if (e >= 0)
{
if (e_ptrs[e].behavior & MAT_BBS)
{
*p++ = 'B';
if (how_big)
*p++ = ' ';
}
if (e_ptrs[e].behavior & MAT_CM)
{
*p++ = 'C';
if (how_big)
*p++ = ' ';
}
if (e_ptrs[e].behavior & MAT_DYNAM)
{
*p++ = 'D';
if (how_big)
*p++ = ' ';
}
if (how_big && (e_ptrs[e].behavior & MAT_FORCED))
{
*p++ = 'F';
*p++ = ' ';
}
if (e_ptrs[e].behavior & MAT_HIPRICM)
{
*p++ = 'H';
if (how_big)
*p++ = ' ';
}
if (e_ptrs[e].behavior & MAT_NOCM)
{
*p++ = 'K';
if (how_big)
*p++ = ' ';
}
if (e_ptrs[e].behavior & MAT_LOCAL)
{
*p++ = 'L';
if (how_big)
{
if (e_ptrs[e].node_cost >= 0)
(void) sprintf (j, "<%d ", (e_ptrs[e].node_cost) + 1);
else
(void) sprintf (j, ">%d ", -(e_ptrs[e].node_cost) - 1);
q = j;
while (*q)
*p++ = *q++;
}
}
if (how_big && (e_ptrs[e].behavior & MAT_NOMAIL24))
{
*p++ = 'M';
*p++ = ' ';
}
if (e_ptrs[e].behavior & MAT_NOREQ)
{
*p++ = 'N';
if (how_big)
*p++ = ' ';
}
if (e_ptrs[e].behavior & MAT_OUTONLY)
{
*p++ = 'S';
if (how_big)
*p++ = ' ';
}
if (e_ptrs[e].behavior & MAT_NOOUT)
{
*p++ = 'R';
if (how_big)
*p++ = ' ';
}
if (how_big && (e_ptrs[e].behavior & MAT_NOOUTREQ))
*p++ = 'X';
}
*p = '\0';
return (ebuf);
}
void
do_ready (char *str)
{
if (fullscreen && un_attended)
{
if (!doing_poll)
{
clear_filetransfer ();
}
(void) sprintf (junk, "%-2d/%-6.6s", cur_event + 1, estring (cur_event, 0));
sb_move (settingswin, SET_EVNT_ROW, SET_COL);
sb_puts (settingswin, junk);
sb_move (settingswin, SET_STAT_ROW, SET_COL);
sb_puts (settingswin, str);
sb_show ();
}
}
void
list_next_event ()
{
int i;
char *p;
char j[100];
i = time_to_next (0);
if ((next_event >= 0) && fullscreen)
{
clear_filetransfer ();
(void) sprintf (j, MSG_TXT (M_NEXT_EVENT), next_event + 1, i);
sb_move (filewin, 1, 2);
sb_puts (filewin, j);
p = estring (next_event, 1);
if (*p != '\0')
{
(void) sprintf (j, MSG_TXT (M_EVENT_FLAGS), p);
sb_move (filewin, 2, 2);
sb_puts (filewin, j);
}
if (netmail != NULL)
scan_netmail (j);
sb_show ();
} /* If next event and fullscreen */
}
/* Temp area j passed from function above. Sorta messy but can't
afford too many stack variables on DOS */
static void
scan_netmail (char *j)
{
int i, k;
short iReadT[2];
FILE *fpt;
struct FILEINFO dta = {0};
if (*netmail == '$')
{
if (SquishScan (netmail + 1))
{
sb_move (filewin, 2, 50);
sb_puts (filewin, MSG_TXT (M_UNREAD_NETMAIL));
}
}
else
{
(void) strcpy (j, netmail);
(void) strcat (j, "LASTREAD"); /* Full path to LASTREAD */
fpt = share_fopen (j, read_binary, DENY_WRITE); /* Open the file */
if (fpt != NULL)
{
/*
* Try to read two records. If there are two, the first record is the
* current pointer and the second one is the last-read. If there is
* one record, it is the last-read.
*/
i = fread (iReadT, sizeof (short), 2, fpt); /* Get lastread ptr */
(void) fclose (fpt); /* Then close the file*/
if (i)
{
int f = 0;
k = iReadT[i - 1]; /* Last msg read */
(void) strcpy (j, netmail);
(void) strcat (j, "*.msg"); /* Wildcard for .MSG */
while (!dfind (&dta, j, f)) /* If there are any, */
{
f = 1;
if (atoi (dta.name) > k) /* See if one's more */
{
sb_move (filewin, 2, 50);
sb_puts (filewin, MSG_TXT (M_UNREAD_NETMAIL));
break;
}
}
if (f)
(void) dfind (&dta, NULL, 2);
} /* If any records read from LASTREAD */
} /* If we were able to open LASTREAD */
} /* If the user specified NetMail */
}